package cn.edu.xmu.datamining.tangzk.mralgos.kmeans;

import java.io.DataInput;
import java.io.DataOutput;
import java.io.IOException;

import org.apache.hadoop.io.WritableComparable;

public class ClusterCentroidWritable implements
		WritableComparable<ClusterCentroidWritable> {

	// cluster label
	private int c;
	// true indicates the value is a cluster center, false is a normal sample
	// default is false
	private boolean isCenter = false;
	// cluster sample point
	private SampleWritable sample = new SampleWritable();

	public ClusterCentroidWritable() {

	}

	public ClusterCentroidWritable(int c, String str) {
		this.c = c;
		this.sample = SampleWritable.parseSample(str);
	}

	public ClusterCentroidWritable(int c, SampleWritable sample) {
		this.c = c;
		this.sample = sample;
	}

	@Override
	public void write(DataOutput out) throws IOException {
		out.writeInt(this.c);
		out.writeBoolean(this.isCenter);
		sample.write(out);
	}

	@Override
	public void readFields(DataInput in) throws IOException {
		this.c = in.readInt();
		this.isCenter = in.readBoolean();
		sample.readFields(in);
	}

	@Override
	public int compareTo(ClusterCentroidWritable o) {
		if (this.c != o.c) {
			return this.c - o.c;
		} else if (this.isCenter != o.isCenter) {
			// Boolean.compare: false < true
			return -Boolean.compare(this.isCenter, o.isCenter);
		} else {
			return this.sample.compareTo(o.sample);
		}
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof ClusterCentroidWritable)) {
			return false;
		}
		ClusterCentroidWritable o = (ClusterCentroidWritable) obj;
		if (this.c != o.c || this.isCenter != o.isCenter) {
			return false;
		} else {
			return this.sample.equals(o.sample);
		}
	}

	@Override
	public int hashCode() {
		return this.c * 591 + (this.isCenter ? 1 : 2) * 431
				+ this.sample.hashCode();
	}

	@Override
	public String toString() {
		return this.c + ": " + (this.isCenter ? 0 : 1) + ": " + this.sample;
	}

	public int getC() {
		return c;
	}

	public void setC(int c) {
		this.c = c;
	}

	public boolean isCenter() {
		return isCenter;
	}

	public void setCenter(boolean isCenter) {
		this.isCenter = isCenter;
	}

	public SampleWritable getSample() {
		return sample;
	}

	public void setSample(SampleWritable sample) {
		this.sample = sample;
	}

}
